home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 076-100 / disk_092 / as6502 / assm3.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  10KB  |  552 lines

  1. #include "stdio.h"
  2. #include "assm.d1"
  3. #include "assm.d2"
  4. #include "ctype.h"
  5.  
  6. /* class 1 machine operations processor - 1 byte, no operand field */
  7.  
  8. class1()
  9. {
  10.     if (pass == LAST_PASS) {
  11.         loadlc(loccnt, 0, 1);
  12.         loadv(opval, 0, 1);
  13.         println();
  14.     }
  15.     loccnt++;
  16. }
  17.  
  18.  
  19. /* class 2 machine operations processor - 2 byte, relative addressing */
  20.  
  21. class2(ip)
  22.     int *ip;
  23. {
  24.  
  25.     if (pass == LAST_PASS) {
  26.         loadlc(loccnt, 0, 1);
  27.         loadv(opval, 0, 1);
  28.         while (prlnbuf[++(*ip)] == ' ');
  29.         if (evaluate(ip) != 0) {
  30.             loccnt += 2;
  31.             return;
  32.         }
  33.         loccnt += 2;
  34.         if ((value -= loccnt) >= -128 && value < 128) {
  35.             loadv(value, 1, 1);
  36.             println();
  37.         }
  38.         else error("Invalid branch address");
  39.     }
  40.     else loccnt += 2;
  41. }
  42.  
  43.  
  44. /* class 3 machine operations processor - various addressing modes */
  45.  
  46. class3(ip)
  47.     int *ip;
  48. {
  49.     char    ch;
  50.     int    code;
  51.     int    flag;
  52.     int    i;
  53.     int    ztmask;
  54.  
  55.     while ((ch = prlnbuf[++(*ip)]) == ' ');
  56.     switch(ch) {
  57.     case 0:
  58.     case ';':
  59.         error("Operand field missing");
  60.         return;
  61.     case 'A':
  62.     case 'a':
  63.         if ((ch = prlnbuf[*ip + 1]) == ' ' || ch == 0) {
  64.             flag = ACC;
  65.             break;
  66.         }
  67.     default:
  68.         switch(ch = prlnbuf[*ip]) {
  69.         case '#': case '=':
  70.             flag = IMM1 | IMM2;
  71.             ++(*ip);
  72.             break;
  73.         case '(':
  74.             flag = IND | INDX | INDY;
  75.             ++(*ip);
  76.             break;
  77.         default:
  78.             flag = ABS | ZER | ZERX | ABSX | ABSY | ABSY2 | ZERY;
  79.         }
  80.         if ((flag & (INDX | INDY | ZER | ZERX | ZERY) & opflg) != 0)
  81.             udtype = UNDEFAB;
  82.         if (evaluate(ip) != 0)
  83.             return;
  84.         if (zpref != 0) {
  85.             flag &= (ABS | ABSX | ABSY | ABSY2 | IND | IMM1 | IMM2);
  86.             ztmask = 0;
  87.         }
  88.         else ztmask = ZER | ZERX | ZERY;
  89.         code = 0;
  90.         i = 0;
  91.         while (( ch = prlnbuf[(*ip)++]) != ' ' && ch != 0 && i++ < 4) {
  92.             code *= 8;
  93.             switch(ch) {
  94.             case ')':        /* ) = 4 */
  95.                 ++code;
  96.             case ',':        /* , = 3 */
  97.                 ++code;
  98.             case 'X':        /* X = 2 */
  99.             case 'x':
  100.                 ++code;
  101.             case 'Y':        /* Y = 1 */
  102.             case 'y':
  103.                 ++code;
  104.                 break;
  105.             default:
  106.                 flag = 0;
  107.             }
  108.         }
  109.         switch(code) {
  110.         case 0:        /* no termination characters */
  111.             flag &= (ABS | ZER | IMM1 | IMM2);
  112.             break;
  113.         case 4:        /* termination = ) */
  114.             flag &= IND;
  115.             break;
  116.         case 25:        /* termination = ,Y */
  117.             flag &= (ABSY | ABSY2 | ZERY);
  118.             break;
  119.         case 26:        /* termination = ,X */
  120.             flag &= (ABSX | ZERX);
  121.             break;
  122.         case 212:        /* termination = ,X) */
  123.             flag &= INDX;
  124.             break;
  125.         case 281:        /* termination = ),Y */
  126.             flag &= INDY;
  127.             break;
  128.         default:
  129.             flag = 0;
  130.         }
  131.     }
  132.     if ((opflg &= flag) == 0) {
  133.         error("Invalid addressing mode");
  134.         return;
  135.     }
  136.     if ((opflg & ztmask) != 0)
  137.         opflg &= ztmask;
  138.     switch(opflg) {
  139.     case ACC:        /* single byte - class 3 */
  140.         if (pass == LAST_PASS) {
  141.             loadlc(loccnt, 0, 1);
  142.             loadv(opval + 8, 0, 1);
  143.             println();
  144.         }
  145.         loccnt++;
  146.         return;
  147.     case ZERX: case ZERY:    /* double byte - class 3 */
  148.         opval += 4;
  149.     case INDY:
  150.         opval += 8;
  151.     case IMM2:
  152.         opval += 4;
  153.     case ZER:
  154.         opval += 4;
  155.     case INDX: case IMM1:
  156.         if (pass == LAST_PASS) {
  157.             loadlc(loccnt, 0, 1);
  158.             loadv(opval, 0, 1);
  159.             loadv(value, 1, 1);
  160.             println();
  161.         }
  162.         loccnt += 2;
  163.         return;
  164.     case IND:        /* triple byte - class 3 */
  165.         opval += 16;
  166.     case ABSX:
  167.     case ABSY2:
  168.         opval += 4;
  169.     case ABSY:
  170.         opval += 12;
  171.     case ABS:
  172.         if (pass == LAST_PASS) {
  173.             opval += 12;
  174.             loadlc(loccnt, 0, 1);
  175.             loadv(opval, 0, 1);
  176.             loadv(value, 1, 1);
  177.             loadv(value >> 8, 2, 1);
  178.             println();
  179.         }
  180.         loccnt += 3;
  181.         return;
  182.     default:
  183.         error("Invalid addressing mode");
  184.         return;
  185.     }
  186. }
  187.  
  188. /* pseudo operations processor */
  189.  
  190. pseudo(ip)
  191.     int *ip;
  192. {
  193.     int    count;
  194.     int    i,j;
  195.     int    tvalue;
  196.  
  197.     switch(opval) {
  198.     case 0:                /* .byte pseudo */
  199.         labldef(loccnt);
  200.         loadlc(loccnt, 0, 1);
  201.         while (prlnbuf[++(*ip)] == ' ');    /*    field    */
  202.         count = 0;
  203.         do {
  204.             if (prlnbuf[*ip] == '"') {
  205.                 while ((tvalue = prlnbuf[++(*ip)]) != '"') {
  206.                     if (tvalue == 0) {
  207.                         error("Unterminated ASCII string");
  208.                         return;
  209.                     }
  210.                     if (tvalue == '\\')
  211.                         switch(tvalue = prlnbuf[++(*ip)]) {
  212.                         case 'n':
  213.                             tvalue = '\n';
  214.                             break;
  215.                         case 't':
  216.                             tvalue = '\t';
  217.                             break;
  218.                         }
  219.                     loccnt++;
  220.                     if (pass == LAST_PASS) {
  221.                         loadv(tvalue, count, 1);
  222.                         if (++count >= 3) {
  223.                             println();
  224.                             for (i = 0; i < SFIELD; i++)
  225.                                 prlnbuf[i] = ' ';
  226.                             prlnbuf[i] = 0;
  227.                             count = 0;
  228.                             loadlc(loccnt, 0, 1);
  229.                         }
  230.                     }
  231.                 }
  232.                 ++(*ip);
  233.             }
  234.             else {
  235.                 if (evaluate(ip) != 0) {
  236.                     loccnt++;
  237.                     return;
  238.                 }
  239.                 loccnt++;
  240.                 if (value > 0xff) {
  241.                     error("Operand field size error");
  242.                     return;
  243.                 }
  244.                 else if (pass == LAST_PASS) {
  245.                     loadv(value, count, 1);
  246.                     if (++count >= 3) {
  247.                         println();
  248.                         for (i = 0; i < SFIELD; i++)
  249.                             prlnbuf[i] = ' ';
  250.                         prlnbuf[i] = 0;
  251.                         count = 0;
  252.                         loadlc(loccnt, 0, 1);
  253.                     }
  254.                 }
  255.             }
  256.         } while (prlnbuf[(*ip)++] == ',');
  257.         if ((pass == LAST_PASS) && (count != 0))
  258.             println();
  259.         return;
  260.     case 1:                /* = pseudo */
  261.         while (prlnbuf[++(*ip)] == ' ');
  262.         if (evaluate(ip) != 0)
  263.             return;
  264.         labldef(value);
  265.         if (pass == LAST_PASS) {
  266.             loadlc(value, 1, 0);
  267.             println();
  268.         }
  269.         return;
  270.     case 2:                /* .word pseudo */
  271.         labldef(loccnt);
  272.         loadlc(loccnt, 0, 1);
  273.         while (prlnbuf[++(*ip)] == ' ');
  274.         do {
  275.             if (evaluate(ip) != 0) {
  276.                 loccnt += 2;
  277.                 return;
  278.             }
  279.             loccnt += 2;
  280.             if (pass == LAST_PASS) {
  281.                 loadv(value, 0, 1);
  282.                 loadv(value>>8, 1, 1);
  283.                 println();
  284.                 for (i = 0; i < SFIELD; i++)
  285.                     prlnbuf[i] = ' ';
  286.                 prlnbuf[i] = 0;
  287.                 loadlc(loccnt, 0, 1);
  288.             }
  289.         } while (prlnbuf[(*ip)++] == ',');
  290.         return;
  291.     case 3:                /* *= pseudo */
  292.         while (prlnbuf[++(*ip)] == ' ');
  293.         if (prlnbuf[*ip] == '*') {
  294.             if (evaluate(ip) != 0)
  295.                 return;
  296.             if (undef != 0) {
  297.                 error("Undefined symbol in operand field.");
  298.                 return;
  299.             }
  300.             tvalue = loccnt;
  301.         }
  302.         else {
  303.             if (evaluate(ip) != 0)
  304.                 return;
  305.             if (undef != 0) {
  306.                 error("Undefined symbol in operand field.");
  307.                 return;
  308.             }
  309.             tvalue = value;
  310.         }
  311.         loccnt = value;
  312.         labldef(tvalue);
  313.         if (pass == LAST_PASS) {
  314.             objcnt = 0;
  315.             loadlc(tvalue, 1, 0);
  316.             println();
  317.         }
  318.         return;
  319.     case 4:                /* .list pseudo */
  320.         if (lflag >= 0)
  321.             lflag = 1;
  322.         return;
  323.     case 5:                /* .nlst pseudo */
  324.         if (lflag >= 0)
  325.             lflag = iflag;
  326.         return;
  327.     case 6:                /* .dbyt pseudo */
  328.         labldef(loccnt);
  329.         loadlc(loccnt, 0, 1);
  330.         while (prlnbuf[++(*ip)] == ' ');
  331.         do {
  332.             if (evaluate(ip) != 0) {
  333.                 loccnt += 2;
  334.                 return;
  335.             }
  336.             loccnt += 2;
  337.             if (pass == LAST_PASS) {
  338.                 loadv(value>>8, 0, 1);
  339.                 loadv(value, 1, 1);
  340.                 println();
  341.                 for (i = 0; i < SFIELD; i++)
  342.                     prlnbuf[i] = ' ';
  343.                 prlnbuf[i] = 0;
  344.                 loadlc(loccnt, 0, 1);
  345.             }
  346.         } while (prlnbuf[(*ip)++] == ',');
  347.         return;
  348.     case 7:                    /* .page pseudo  */
  349.         if (pagesize == 0) return;
  350.         while (prlnbuf[++(*ip)] == ' ');
  351.         if (prlnbuf[(*ip)] == '"')
  352.             {
  353.             i=0;
  354.             while ((tvalue = prlnbuf[++(*ip)]) != '"')
  355.                 {
  356.                 if (tvalue =='\0') {
  357.                     error("Unterminated ASCII string");
  358.                     return; }
  359.                 titlbuf[i++] = tvalue;
  360.                 if (i == titlesize) {
  361.                     error("Title too long");
  362.                     return; }
  363.                 }
  364.             if (i<titlesize) for (j=i; j<titlesize; j++) titlbuf[j]=' ';
  365.             }
  366.         if (lflag > 0) printhead();
  367.         return;
  368.     }
  369. }
  370.  
  371. /* evaluate expression */
  372.  
  373. evaluate(ip)
  374.    int    *ip;
  375. {
  376.     int    tvalue;
  377.     int    invalid;
  378.     int    parflg, value2;
  379.     char    ch;
  380.     char    op;
  381.     char    op2;
  382.  
  383.     op = '+';
  384.     parflg = zpref = undef = value = invalid = 0;
  385. /* hcj: zpref should reflect the value of the expression, not the value of
  386.    the intermediate symbols
  387. */
  388.     while ((ch=prlnbuf[*ip]) != ' ' && ch != ')' && ch != ',' && ch != ';') {
  389.         tvalue = 0;
  390.         if (ch == '$' || ch == '@' || ch == '%')
  391.             tvalue = colnum(ip);
  392.         else if (ch >= '0' && ch <= '9')
  393.             tvalue = colnum(ip);
  394.         else if (ch >= 'a' && ch <= 'z')
  395.             tvalue = symval(ip);
  396.         else if (ch >= 'A' && ch <= 'Z')
  397.             tvalue = symval(ip);
  398.         else if ((ch == '_') || (ch == '.'))
  399.             tvalue = symval(ip);
  400.         else if (ch == '*') {
  401.             tvalue = loccnt;
  402.             ++(*ip);
  403.         }
  404.         else if (ch == '\'') {
  405.             ++(*ip);
  406.             tvalue = prlnbuf[*ip] & 0xff;
  407.             ++(*ip);
  408.         }
  409.         else if (ch == '[') {
  410.             if (parflg == 1) {
  411.                 error("Too many ['s in expression");
  412.                 invalid++;
  413.             }
  414.             else {
  415.                 value2 = value;
  416.                 op2 = op;
  417.                 value = tvalue = 0;
  418.                 op = '+';
  419.                 parflg = 1;
  420.             }
  421.             goto next;
  422.         }
  423.         else if (ch == ']') {
  424.             if (parflg == 0) {
  425.                 error("No matching [ for ] in expression");
  426.                 invalid++;
  427.             }
  428.             else {
  429.                 parflg = 0;
  430.                 tvalue = value;
  431.                 value = value2;
  432.                 op = op2;
  433.             }
  434.             ++(*ip);
  435.         }
  436.         switch(op) {
  437.         case '+':
  438.             value += tvalue;
  439.             break;
  440.         case '-':
  441.             value -= tvalue;
  442.             break;
  443.         case '/':
  444.             value = (unsigned) value/tvalue;
  445.             break;
  446.         case '*':
  447.             value *= tvalue;
  448.             break;
  449.         case '%':
  450.             value = (unsigned) value%tvalue;
  451.             break;
  452.         case '^':
  453.             value ^= tvalue;
  454.             break;
  455.         case '~':
  456.             value = ~tvalue;
  457.             break;
  458.         case '&':
  459.             value &= tvalue;
  460.             break;
  461.         case '|':
  462.             value |= tvalue;
  463.             break;
  464.         case '>':
  465.             tvalue >>= 8;        /* fall through to '<' */
  466.         case '<':
  467.             if (value != 0) {
  468.                 error("High or low byte operator not first in operand field");
  469.             }
  470.             value = tvalue & 0xff;
  471.             zpref = 0;
  472.             break;
  473.         default:
  474.             invalid++;
  475.         }
  476.         if ((op=prlnbuf[*ip]) == ' '
  477.                 || op == ')'
  478.                 || op == ','
  479.                 || op == ';')
  480.             break;
  481.         else if (op != ']')
  482. next:            ++(*ip);
  483.     }
  484.     if (parflg == 1) {
  485.         error("Missing ] in expression");
  486.         return(1);
  487.     }
  488.     if (value < 0 || value >= 256) {
  489.         zpref = 1;
  490.     }
  491.     if (undef != 0) {
  492.         if (pass != FIRST_PASS) {
  493.             error("Undefined symbol in operand field");
  494.             invalid++;
  495.         }
  496.         value = 0;
  497.     }
  498.     else if (invalid != 0)
  499.     {
  500.         error("Invalid operand field");
  501.     }
  502.     else {
  503. /*
  504.  This is the only way out that may not signal error
  505. */
  506.         if (value < 0 || value >= 256) {
  507.             zpref = 1;
  508.         }
  509.         else {
  510.             zpref = 0;
  511.         }
  512.     }
  513.     return(invalid);
  514. }
  515.  
  516. /* collect number operand        */
  517.  
  518. colnum(ip)
  519.     int    *ip;
  520. {
  521.     int    mul;
  522.     int    nval;
  523.     char    ch;
  524.  
  525.     nval = 0;
  526.     if ((ch = prlnbuf[*ip]) == '$')
  527.         mul = 16;
  528.     else if (ch >= '1' && ch <= '9') {
  529.         mul = 10;
  530.         nval = ch - '0';
  531.     }
  532.     else if (ch == '@' || ch == '0')
  533.         mul = 8;
  534.     else if (ch == '%')
  535.         mul = 2;
  536.     while ((ch = prlnbuf[++(*ip)] - '0') >= 0) {
  537.         if (ch > 9) {
  538.             ch -= ('A' - '9' - 1);
  539.             if (ch > 15)
  540.                 ch -= ('a' - 'A');
  541.             if (ch > 15)
  542.                 break;
  543.             if (ch < 10)
  544.                 break;
  545.         }
  546.         if (ch >= mul)
  547.             break;
  548.         nval = (nval * mul) + ch;
  549.     }
  550.     return(nval);
  551. }
  552.